package com.mes.utils;

import com.mes.entity.User;
import com.yy.base.util.StringUtil;
import com.yy.base.util.UserUtil;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@SuppressWarnings("unchecked")
public class GenerateCodeUtil {
	private static final SimpleDateFormat yyyyMM = new SimpleDateFormat("yyMM");
	private static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyMMdd");
	private DBConctionQuery query = null;
	
	public GenerateCodeUtil() {
		query = new DBConctionQuery();
	}
	
	/**
	 * 根据表ID，字段名获取编码规则结果
	 */
	public static synchronized String getCode(String tableName, String fieldName) {
		return getCode(tableName, fieldName, null);
	}
	/**
	 * 根据表ID，字段名获取编码规则结果
	 */
	public static synchronized String getCode(String tableName, String fieldName, String orgId) {
		return getCode(tableName, fieldName, null, orgId);
	}
	/**
	 * 根据表ID，字段名获取编码规则结果
	 */
	public static synchronized String getCode(String tableName, String fieldName, String param, String orgId) {
		DBConctionQuery query = null;
		try {
			query = new DBConctionQuery();
			return query.callBack("{ call Generate_Code(?, ?, ?, ?, ?) }", tableName, fieldName, param, orgId);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		} finally {
			if (query != null) {
				query.close();
			}
		}
	}
	/**
	 * 根据表ID，字段名获取编码规则结果
	 */
	public static synchronized String[] getCode(String tableName, String fieldName, int size) {
		return getCode(tableName, fieldName, null, size);
	}
	/**
	 * 根据表ID，字段名获取编码规则结果
	 */
	public static synchronized String[] getCode(String tableName, String fieldName, String param, int size) {
		return getCode(tableName, fieldName, param, null, size);
	}
	/**
	 * 根据表ID，字段名获取编码规则结果
	 */
	public static synchronized String[] getCode(String tableName, String fieldName, String param, String orgId, int size) {
		GenerateCodeUtil util = new GenerateCodeUtil();
		try {
			List<Map<String, Object>> list = util.getCodeRuleList(tableName);
			for (Map<String, Object> rule : list) {
				// 自动生成
				if (((String)rule.get("COLUMNNAME")).equalsIgnoreCase(fieldName)) {
					String[] codes = new String[size];
					for (int i = 0;i < size; i++) {
						codes[i] = util.createCode(rule, param, orgId);
					}
					return codes;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			util.close();
		}
		throw new RuntimeException("字段" + fieldName + "未设置编码规则");
	}
	
	private List<Map<String, Object>> getCodeRuleList(String tableId) throws Exception {
		String sql = "select ad_table_id from ad_table where upper(tablename) = '" + tableId.toUpperCase() + "'";
		String adTableId = tableId;
		Map map = query.queryUnique(sql);
		if (map != null) {
			adTableId = (String)map.get("AD_TABLE_ID");
		}
		sql = "select c.columnname, cr.emes_code_rule_id id, cr.save_date_max, cr.save_org_max, cr.is_generate " +
				" from ad_column c, Emes_Code_Rule cr,Emes_Code_Rule_Object cro " +
				"where c.ad_column_id = cro.ad_column_id " +
				"  and cr.Emes_Code_Rule_Object_id = cro.Emes_Code_Rule_Object_id " +
				"  and cro.ad_table_id = '" + adTableId + "'";
		return query.query(sql);
	}
	
	private String createCode(Map<String, Object> codeRule, String param, String orgId) throws Exception {
		String sql = "select c.code_type, c.code_length, c.code_value, c.sql,cr.isreset, cr.name, cr.emes_code_rule_id id " +
				" from Emes_Code_Rule_Combination c, Emes_Code_Rule cr " +
				"where c.emes_code_rule_id = cr.emes_code_rule_id " +
				"  and cr.Emes_Code_Rule_id = '" + codeRule.get("ID") + "' order by sequence";
		List<Map<String, Object>> list = query.query(sql);
		if (list == null || list.isEmpty()) {
			return null;
		}
		StringBuilder code = new StringBuilder();
		String str = null;
		String saveDateMax = null;
		if ("Y".equals(codeRule.get("SAVE_DATE_MAX"))) {
			// 判断是否存在日期列
			for (Map<String, Object> rule : list) {
				if ("YYYYMM".equals(rule.get("CODE_TYPE")) || "YYMM".equals(rule.get("CODE_TYPE"))) {
					saveDateMax = yyyyMM.format(new Date());
					break;
				} else if ("YYYYMMDD".equals(rule.get("CODE_TYPE")) || "YYMMDD".equals(rule.get("CODE_TYPE"))) {
					saveDateMax = yyyyMMdd.format(new Date());
					break;
				}
			}
		}
		String selfCode = null;
		for (Map<String, Object> rule : list) {
			if ("ORG".equals(rule.get("CODE_TYPE"))) {
				str = getOrgCode();
			} else if ("XL".equals(rule.get("CODE_TYPE"))) {
				if (orgId == null || "Y".equals(codeRule.get("SAVE_ORG_MAX"))) {
					orgId = "AA692B6DA706483A8A9737C4D15A028E";
				}
				str = getSnCode(rule, saveDateMax, orgId);
			} else if ("SELF".equals(rule.get("CODE_TYPE"))) {
				selfCode = getSelfCode((String)rule.get("SQL"), param);
				str = selfCode;
			} else if ("YYYYMM".equals(rule.get("CODE_TYPE")) || "YYMM".equals(rule.get("CODE_TYPE"))) {
				str = yyyyMM.format(new Date());
			} else if ("YYYYMMDD".equals(rule.get("CODE_TYPE")) || "YYMMDD".equals(rule.get("CODE_TYPE"))) {
				str = yyyyMMdd.format(new Date());
			} else {
				str = (String)rule.get("CODE_VALUE");
			}
			code.append(str);
		}
		return code.toString();
	}
	
	private String getOrgCode() throws Exception {
		User user = UserUtil.getUser();
		if (user != null) {
			String orgId = user.getOrgId();
			String sql = "select value from ad_org where ad_org_id = ?";
			Map<String, Object> map = query.queryUnique(sql, orgId);
			if (map != null) {
				return (String)map.get("VALUE");
			}
		}
		throw new RuntimeException("无法获取当前登录用户！");
	}
	
	private String getSelfCode(String sql, String param) throws Exception {
		String obj = param;
		if (param == null) {
			User user = UserUtil.getUser();
			if (user != null) {
				obj = user.getId();
			}
		}
		sql = sql.replace("@AD_User_Id@", "?");
		sql = sql.replace("@AD_User_ID@", "?");
		sql = sql.replace("@Ad_User_Id@", "?");
		sql = sql.replace("@AD_USER_ID@", "?");
		sql = sql.replace("@ad_user_id@", "?");
		sql = sql.replace("@value@", "?");
		Map<String, Object> map = null;
		
		if(sql.contains("?")) {
			map = query.queryUnique(sql, obj);
		} else {
			map = query.queryUnique(sql);
		}
		if (map != null) {
			for (String key : map.keySet()) {
				return (String)map.get(key);
			}
		}
		return "";
	}
	
	private String getSnCode(Map<String, Object> rule, String dateValue, String orgId) throws Exception {
		String sql = "select s.COUNTER_VALUE,s.Emes_SNCOUNTER_ID from Emes_SNCounter s " +
				"where s.Emes_CODE_RULE_ID = '" + rule.get("ID") + "' " +
				"  and s.ad_org_id = '" + orgId + "'";
		if (dateValue != null) {
			sql += " and s.COUNTER_DATE = '" + dateValue + "'";
		} else {
			sql += " and s.COUNTER_DATE is null";
		}
		
		Map<String, Object> sn = query.queryUnique(sql);
		long value = 1;
		if (sn == null) {
			String uuid = StringUtil.getUUID();
			String insert = "insert into Emes_SNCounter (Emes_SNCOUNTER_ID, COUNTER_NAME, COUNTER_VALUE, Emes_CODE_RULE_ID, AD_ORG_ID, COUNTER_DATE) " +
					"values ('" + uuid + "', '" + rule.get("NAME") + "计数器', 2, '" + rule.get("ID") + "', '" + orgId + "',";
			if (dateValue != null) {
				insert += "'" + dateValue + "')";
			} else {
				insert += "'')";
			}
			query.execute(insert);
		} else {
			value = Long.parseLong(sn.get("COUNTER_VALUE") + "");
			String update = "";
			if("Y".equals(String.valueOf(rule.get("ISRESET"))) && ((value + 1)+"").length() > Integer.parseInt(String.valueOf(rule.get("CODE_LENGTH")))){
				update = "update Emes_SNCounter set COUNTER_VALUE = 1 where Emes_SNCOUNTER_ID = '" + sn.get("Emes_SNCOUNTER_ID") + "'";
			}else{
				update = "update Emes_SNCounter set COUNTER_VALUE = " + (value + 1) + " where Emes_SNCOUNTER_ID = '" + sn.get("Emes_SNCOUNTER_ID") + "'";
			}
			query.execute(update);
		}
		int length = (value + "").length();
		StringBuilder code = new StringBuilder();
		int codeLength = Integer.parseInt(rule.get("CODE_LENGTH") + "");
		for (int i = length; i < codeLength; i++) {
			code.append("0");
		}
		code.append(value);
		return code.toString();
	}
	
	private void close() {
		query.close();
	}
}